package org.Image.management.ViewController.pojo;

import cn.hutool.core.io.FileUtil;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Size;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXMLLoader;
import javafx.fxml.JavaFXBuilderFactory;
import javafx.geometry.Insets;
import javafx.geometry.Rectangle2D;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.image.Image;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.GridPane;
import javafx.stage.*;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.Image.management.SpringDataService.Pojo.AppConfig;
import org.Image.management.SpringDataService.Service.Sys_User.Pojo.dto.LoginRequest;
import org.Image.management.SpringDataService.Service.Sys_User.Pojo.dto.UpdatePasswordRequest;
import org.Image.management.ViewCofig.file.FxmlPath;
import org.Image.management.ViewCofig.file.IconPath;
import org.Image.management.ViewService.utils.informationalTips;

import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.function.Consumer;

import static org.Image.management.SpringBootImageManagementApplication.applicationContext;


@Data
@Slf4j
public class SetViewAttribute {
    //当前屏幕大小
    private static final Rectangle2D screenBounds;

    static {
        //获取当前屏幕大小
        screenBounds = Screen.getPrimary().getVisualBounds();
    }

    //当前窗口
    private Stage primaryStage;


    /***
     * 更改视图
     * @param fxml Fxml静态资源
     * @param isEject 弹出显示
     * @param isWindowCentered 设置窗口居中
     */
    public void changeView(FxmlPath fxml, boolean isEject, boolean isWindowCentered) {

        //设置标题
        switch (fxml) {
            case Login -> primaryStage.setTitle("登录页面");
            case Main -> primaryStage.setTitle("图片管理页面");
            case Enroll -> primaryStage.setTitle("注册页面");
            default -> primaryStage.setTitle("错误");
        }

        URL fileURL = fxml.getFileURL();
//        log.info("加载视图：{}=>：{}", fxml.getFileName(), fileURL);

        // 获取解码文件
        FXMLLoader fxmlLoader = new FXMLLoader(fileURL);
        fxmlLoader.setBuilderFactory(new JavaFXBuilderFactory());

        fxmlLoader.setControllerFactory(param -> {
            // 控制器工厂提供bean注入，此处的缺点是不能根据bean名字注入，只能通过class类型注入bean
            // 解决方案：
            // 1、SpringbootJavafxDemoApplication.applicationContext.getBean("Bean Name", Bean.class);
            // 2、@Autowired private ApplicationContext applicationContext;
            // Object bean_name = applicationContext.getBean("bean Name", Bean.class);
            return applicationContext.getBean(param);
        });

        try {
            //转化为舞台
            Scene scene = new Scene(fxmlLoader.load());
            if (!FileUtil.isWindows() || primaryStage.isShowing() ){
                //显示窗口
                primaryStage.hide();
            }
            //设置舞台
            primaryStage.setScene(scene);

        } catch (IOException e) {
            log.error("加载视图失败", e);
        }

        // 弹出显示
        if (isEject) {
            ejectShow();
        }
        //显示窗口
        primaryStage.show();
        // 设置窗口居中
        if (isWindowCentered) {
            windowCentered();
        }


    }


    //设窗口在最顶上显示
    public void ejectShow() {
        //设置置顶
        primaryStage.setAlwaysOnTop(true);
        primaryStage.show();

        //取消置顶
        primaryStage.setAlwaysOnTop(false);
    }

    //窗口居中
    public void windowCentered() {
        double SceneWidth = primaryStage.getScene().getWidth();
        double SceneHeight = primaryStage.getScene().getHeight();
        primaryStage.setX((screenBounds.getWidth() - SceneWidth) / 2);
        primaryStage.setY((screenBounds.getHeight() - SceneHeight) / 2);
    }

    // 设置窗口 icon
    public void setWindowIcon(IconPath Icon) {
        try {
            URL iconURL = Icon.getIconURL();
//            log.info("加载图标：{}", iconURL);
            primaryStage.getIcons().add(new Image(iconURL.openStream()));
        } catch (IOException e) {
            log.error("加载图标失败", e);
        }
    }

    // 文件选择器选择文件路径
    public File getShowOpenDialogFile() {

        //现在只能选择jpg、png格式的图片
        FileChooser fc = new FileChooser();
        FileChooser.ExtensionFilter PngAndJpg = new FileChooser.ExtensionFilter("png,jpg", "*.png","*.jpg");
        FileChooser.ExtensionFilter png = new FileChooser.ExtensionFilter("png", "*.png");
        FileChooser.ExtensionFilter jpg = new FileChooser.ExtensionFilter("jpg", "*.jpg");

        fc.getExtensionFilters().addAll(PngAndJpg,jpg, png);
        fc.setTitle("添加图片");

        return fc.showOpenDialog(primaryStage);
    }

    // 目录选择器 选择文件夹
    public File getDirectoryChooserSelectDirectory() {
        DirectoryChooser dc = new DirectoryChooser();
        dc.setTitle("选择一个文件夹");
        //设置初始目录
        dc.setInitialDirectory(AppConfig.DIRECTORY_CHOOSER_INITIAL_DIRECTORY);
        return dc.showDialog(primaryStage);
    }

    /**
     * @param title         标题
     * @param Icon          图标
     * @param nodeCenter    接收的 node 放在 Center
     * @param isColumnsRows 切换 列和行约束
     * @param value         OK按钮 点击事件
     */
    public void ModifyStage(String title, URL Icon, Node nodeCenter, boolean isColumnsRows, EventHandler<ActionEvent> value) {
        Stage dialog = new Stage();
        dialog.setTitle(title);
        dialog.initOwner(primaryStage);
        //阻止用户与其他窗口交互的对话框，直到该对话框被关闭
        dialog.initModality(Modality.APPLICATION_MODAL); // 模态对话框
        // 设置图标
        try {
            dialog.getIcons().add(new Image(Icon.openStream()));
        } catch (IOException e) {
            log.info("ModifyStage 加载图标失败");
        }
        dialog.setResizable(false);
        BorderPane borderPane = new BorderPane();

        Button yse = new Button("确定");
        Button no = new Button("取消");

        yse.setOnAction(event -> {
            value.handle(event);
            dialog.close();
        });

        no.setOnAction(event -> dialog.close());

        GridPane grid = new GridPane();
        grid.setHgap(10);
        grid.setVgap(10);
        grid.setPadding(new Insets(20, 10, 10, 10));
        grid.add(yse, 0, 0);
        if (isColumnsRows) {
            grid.add(no, 0, 1);
        } else {
            grid.add(no, 1, 0);
        }

        borderPane.setRight(grid);
        borderPane.setCenter(nodeCenter);

        dialog.setScene(new Scene(borderPane));
        dialog.show();
    }

    // 账户找回
    public void ModifyAccountBack(Consumer<LoginRequest> value) {
        // 创建用户名和密码标签和字段
        GridPane grid = new GridPane();
        grid.setHgap(10);
        grid.setVgap(10);
        grid.setPadding(new Insets(20, 10, 10, 10));

        TextField name = new TextField();
        name.setPromptText("请输入用户名称");

        TextField password = new TextField();
        password.setPromptText("请输入密码");


        grid.add(new Label("请输入用户名称:"), 0, 0);
        grid.add(name, 1, 0);

        grid.add(new Label("请输入密码:"), 0, 1);
        grid.add(password, 1, 1);

        ModifyStage("找回账户", IconPath.EMAIL.getIconURL(), grid, true, event -> {
            String nameText = name.getText();
            String passwordText = password.getText();
            value.accept(new LoginRequest(nameText,passwordText));
        });
    }

    // 修改密码
    public void ChangePassword(Consumer<UpdatePasswordRequest> value) {
        // 创建用户名和密码标签和字段
        GridPane grid = new GridPane();
        grid.setHgap(10);
        grid.setVgap(10);
        grid.setPadding(new Insets(20, 10, 10, 10));
        TextField oldPassword = new TextField();
        oldPassword.setPromptText("请输入原来密码");

        TextField password = new TextField();
        password.setPromptText("请输入密码");
        TextField password1 = new TextField();
        password1.setPromptText("请再次输入密码");

        grid.add(new Label("请输入原来密码:"), 0, 0);
        grid.add(oldPassword, 1, 0);

        grid.add(new Label("请输入密码:"), 0, 1);
        grid.add(password, 1, 1);

        grid.add(new Label("请再次输入密码:"), 0, 2);
        grid.add(password1, 1, 2);

        ModifyStage("修改密码", IconPath.EMAIL.getIconURL(), grid, true, event -> {
            String text = password.getText();
            String text1 = password1.getText();
            String oldPasswordText = oldPassword.getText();
            log.info("oldPasswordText:{},Text:{},Text1:{}",oldPasswordText,text,text1);

            if (text.isEmpty() || text1.isEmpty()|| oldPasswordText.isEmpty()) {
                informationalTips.AlertDialogBox(Alert.AlertType.ERROR, IconPath.CRY_FILLING.getIconURL(), "输入密码有空,请重新输入!", "请输入密码的为空", "错误对话框");
                return;
            }
            if (!text.matches(".{8,20}") || !text1.matches(".{8,20}")|| !oldPasswordText.matches(".{8,20}")) {
                informationalTips.AlertDialogBox(Alert.AlertType.ERROR, IconPath.CRY_FILLING.getIconURL(), "密码长度需在8-20字符之间!", "输入密码长度不符合", "错误对话框");
                return;
            }
            if (!text.matches("^(?=.*[A-Za-z])(?=.*\\d)[A-Za-z\\d]{8,}$")
                    || !text1.matches("^(?=.*[A-Za-z])(?=.*\\d)[A-Za-z\\d]{8,}$")
                    || !oldPasswordText.matches("^(?=.*[A-Za-z])(?=.*\\d)[A-Za-z\\d]{8,}$")) {

                informationalTips.AlertDialogBox(Alert.AlertType.ERROR, IconPath.CRY_FILLING.getIconURL(), "密码必须至少8位，包含字母和数字!", "输入密码字符不符合", "错误对话框");
                return;
            }
            if (!text.equals(text1)) {
                informationalTips.AlertDialogBox(Alert.AlertType.ERROR, IconPath.CRY_FILLING.getIconURL(), "输入的密码有错误,请重新输入!", "请输入密码有错误", "错误对话框");
                return;
            }

            value.accept(new UpdatePasswordRequest(0,oldPasswordText,text1));
        });
    }


    // 修改用户名
    public void ModifyUsername(Consumer<String> value) {
//        @NotBlank(message = "用户名不能为空且不能只包含空格")
//        @Size(min = 2, max = 20, message = "用户名长度需在2-20字符之间")
        // 创建用户名和密码标签和字段
        GridPane grid = new GridPane();
        grid.setHgap(10);
        grid.setVgap(10);
        grid.setPadding(new Insets(20, 10, 10, 10));

        TextField Text = new TextField();
        Text.setPromptText("请输入名称");

        grid.add(new Label("请输入名称:"), 0, 0);
        grid.add(Text, 1, 0);
        ModifyStage("修改名称", IconPath.EMAIL.getIconURL(), grid, false, event -> {

            String text = Text.getText();


            if (text.isEmpty()) {
                informationalTips.AlertDialogBox(Alert.AlertType.ERROR, IconPath.CRY_FILLING.getIconURL(), "输入用户名称有空,请重新输入!", "请输入密码的为空", "错误对话框");
                return;
            }
            if (!text.matches(".{2,20}")) {
                informationalTips.AlertDialogBox(Alert.AlertType.ERROR, IconPath.CRY_FILLING.getIconURL(), "用户名称长度需在8-20字符之间!", "输入密码长度不符合", "错误对话框");
                return;
            }

            value.accept(text);
        });

    }
}